//
//  ZZSegmentedController.m
//  zhengzai-tv
//
//  Created by SC on 16/6/20.
//  Copyright © 2016年 zhengzai.tv. All rights reserved.
//

#import "ZZSegmentedController.h"
#import "ZZSegmentedViewModel.h"
#import <objc/runtime.h>
#import "RZDataBinding.h"

@interface PrivateTransitionContext : NSObject <UIViewControllerContextTransitioning>

- (instancetype)initWithFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController goingRight:(BOOL)goingRight;
@property (nonatomic, copy) void (^completionBlock)(BOOL didComplete);
@property (nonatomic, assign, getter=isAnimated) BOOL animated;
@property (nonatomic, assign, getter=isInteractive) BOOL interactive;

@end

@interface PrivateAnimatedTransition : NSObject <UIViewControllerAnimatedTransitioning>
@end

@interface ZZSegmentedController ()

@property (nonatomic, strong, readwrite) UISegmentedControl *segmentedControl;
@property (nonatomic, strong) UIViewController *currentViewController;
@property (nonatomic, strong) ZZSegmentedViewModel *viewModel;
@property (nonatomic, copy) NSArray *viewControllers;

@end

@implementation ZZSegmentedController

@synthesize viewModel = _viewModel;

- (void)bindViewModel
{
    [super bindViewModel];
    [self.viewModel rz_addTarget:self action:@selector(viewControllersChange:) forKeyPathChange:@"viewControllers"];
}

- (void)viewControllersChange:(id)change
{
    _viewControllers = [change objectForKey:kRZDBChangeKeyNew];
    self.currentViewController = (self.currentViewController ? : self.viewControllers[self.segmentedControl.selectedSegmentIndex]);
    [self initialize];
}

- (void)initialize {
    NSArray *items = [self.viewControllers valueForKey:@"segmentedControlItem"];
    
    self.segmentedControl = [[UISegmentedControl alloc] initWithItems:items];
    CGRect frame = self.segmentedControl.frame;
    frame.size.height = 30.0f;
    frame.size.width = items.count * 75.0f;
    self.segmentedControl.frame = frame;
    self.segmentedControl.layer.cornerRadius = 15.0f;
    self.segmentedControl.layer.masksToBounds = YES;
    self.segmentedControl.layer.borderWidth = 1.0f;
    self.segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor;
    self.segmentedControl.selectedSegmentIndex = 0;
    self.segmentedControl.tintColor = [UIColor whiteColor];
    
    self.navigationItem.titleView = self.segmentedControl;
    [self.segmentedControl addTarget:self action:@selector(segmentedChange:) forControlEvents:UIControlEventValueChanged];
}

- (void)setCurrentViewController:(UIViewController *)currentViewController
{
    [self _transitionToChildViewController:currentViewController fromVC:_currentViewController];
    _currentViewController = currentViewController;
}

- (void)_transitionToChildViewController:(UIViewController *)toViewController fromVC:(UIViewController *)fromViewController
{
    toViewController.view.frame = self.view.bounds;
    
    [fromViewController willMoveToParentViewController:nil];
    [self addChildViewController:toViewController];
    
    if (!fromViewController) {
        [self.view addSubview:toViewController.view];
        [toViewController didMoveToParentViewController:self];
        return;
    }
    
    id<UIViewControllerAnimatedTransitioning> animator = [[PrivateAnimatedTransition alloc] init];
    
    NSUInteger fromIndex = [self.viewControllers indexOfObject:fromViewController];
    NSUInteger toIndex = [self.viewControllers indexOfObject:toViewController];
    PrivateTransitionContext *transitionContext = [[PrivateTransitionContext alloc] initWithFromViewController:fromViewController toViewController:toViewController goingRight:toIndex > fromIndex];
    
    transitionContext.animated = YES;
    transitionContext.interactive = NO;
    transitionContext.completionBlock = ^(BOOL didComplete) {
        [fromViewController.view removeFromSuperview];
        [fromViewController removeFromParentViewController];
        [toViewController didMoveToParentViewController:self];
        
        if ([animator respondsToSelector:@selector(animationEnded:)]) {
            [animator animationEnded:didComplete];
        }
        self.segmentedControl.userInteractionEnabled = YES;
    };
    
    self.segmentedControl.userInteractionEnabled = NO;
    [animator animateTransition:transitionContext];
}

- (void)segmentedChange:(UISegmentedControl *)segment
{
    self.currentViewController = self.viewControllers[segment.selectedSegmentIndex];
}

@end

static void *ZZSegmentedControlItemKey = &ZZSegmentedControlItemKey;

@implementation UIViewController (ZZSegmentedControlItem)

- (NSString *)segmentedControlItem {
    return objc_getAssociatedObject(self, ZZSegmentedControlItemKey);
}

- (void)setSegmentedControlItem:(NSString *)segmentedControlItem {
    objc_setAssociatedObject(self, ZZSegmentedControlItemKey, segmentedControlItem, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

#pragma mark - Private Transitioning Classes
@interface PrivateTransitionContext ()

@property (nonatomic, strong) NSDictionary *privateViewControllers;
@property (nonatomic, assign) CGRect privateDisappearingFromRect;
@property (nonatomic, assign) CGRect privateAppearingFromRect;
@property (nonatomic, assign) CGRect privateDisappearingToRect;
@property (nonatomic, assign) CGRect privateAppearingToRect;
@property (nonatomic, weak) UIView *containerView;
@property (nonatomic, assign) UIModalPresentationStyle presentationStyle;

@end

@implementation PrivateTransitionContext

- (instancetype)initWithFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController goingRight:(BOOL)goingRight {
    NSAssert ([fromViewController isViewLoaded] && fromViewController.view.superview, @"The fromViewController view must reside in the container view upon initializing the transition context.");
    self = [super init];
    if (self) {
        self.presentationStyle = UIModalPresentationCustom;
        self.containerView = fromViewController.view.superview;
        self.privateViewControllers = @{
                                        UITransitionContextFromViewControllerKey:fromViewController,
                                        UITransitionContextToViewControllerKey:toViewController,
                                        };
        
        CGFloat travelDistance = (goingRight ? -self.containerView.bounds.size.width : self.containerView.bounds.size.width);
        self.privateDisappearingFromRect = self.privateAppearingToRect = self.containerView.bounds;
        self.privateDisappearingToRect = CGRectOffset (self.containerView.bounds, travelDistance, 0);
        self.privateAppearingFromRect = CGRectOffset (self.containerView.bounds, -travelDistance, 0);
    }
    
    return self;
}

- (CGRect)initialFrameForViewController:(UIViewController *)viewController {
    if (viewController == [self viewControllerForKey:UITransitionContextFromViewControllerKey]) {
        return self.privateDisappearingFromRect;
    } else {
        return self.privateAppearingFromRect;
    }
}

- (CGRect)finalFrameForViewController:(UIViewController *)viewController {
    if (viewController == [self viewControllerForKey:UITransitionContextFromViewControllerKey]) {
        return self.privateDisappearingToRect;
    } else {
        return self.privateAppearingToRect;
    }
}

- (UIViewController *)viewControllerForKey:(NSString *)key {
    return self.privateViewControllers[key];
}

- (UIView *)viewForKey:(NSString *)key
{
    return nil;
}

- (CGAffineTransform)targetTransform
{
    return CGAffineTransformIdentity;
}

- (void)completeTransition:(BOOL)didComplete {
    if (self.completionBlock) {
        self.completionBlock (didComplete);
    }
}

- (BOOL)transitionWasCancelled { return NO; }

- (void)updateInteractiveTransition:(CGFloat)percentComplete {}
- (void)finishInteractiveTransition {}
- (void)cancelInteractiveTransition {}

@end

@implementation PrivateAnimatedTransition

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.3;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    
    // When sliding the views horizontally in and out, figure out whether we are going left or right.
    BOOL goingRight = ([transitionContext initialFrameForViewController:toViewController].origin.x < [transitionContext finalFrameForViewController:toViewController].origin.x);
    CGFloat travelDistance = [transitionContext containerView].bounds.size.width;
    CGAffineTransform travel = CGAffineTransformMakeTranslation (goingRight ? travelDistance : -travelDistance, 0);
    
    [[transitionContext containerView] addSubview:toViewController.view];
    toViewController.view.alpha = 0;
    toViewController.view.transform = CGAffineTransformInvert (travel);
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 options:0x00 animations:^{
        fromViewController.view.transform = travel;
        fromViewController.view.alpha = 0;
        toViewController.view.transform = CGAffineTransformIdentity;
        toViewController.view.alpha = 1;
    } completion:^(BOOL finished) {
        fromViewController.view.transform = CGAffineTransformIdentity;
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

